Risorse per il Lab. Elettronica
Home Page


CAD/CAE

LTspice

PSpice


Sistemi

Arduino

AVR

Raspberry Pi

National Instruments


Risorse

Datasheet

Link

Hardware e Software

Misc






Licenza Creative Commons
*** IL DOWNLOAD DEI SEGUENTI FILE COMPORTA L'IMPLICITA ACCETTAZIONE DELLE SEGUENTI CONDIZIONI ****
I seguenti Documenti, ove non diversamente specificato, sono distribuiti con licenza Creative Commons Attribuzione - Non commerciale - Condividi allo stesso modo 3.0 Unported. E' dunque escluso l'utilizzo per scopi di lucro . Il materiale viene fornito AS-IS senza alcuna garanzia di assenza di errori e/o imprecisioni e senza alcuna forma di supporto. L'Autore è sollevato da ogni responsabilità per qualsiasi utilizzo dei seguenti file. Autore: Francesco Parisi fparisi gmail com


« Indice

AVR ATmega8 con libC - Timer2) Fast PWM a frequenza non regolabil



Ultimo aggiornamento: 14/Giu/2015 



Panoramica sul Timer2 come generatore di forme d'onda

Il Timer2 dei microcontrollori AVR ATmega è un timer a 8 bit, può dunque contare da 0 fino a 255;
ha a disposizione due canali (A e B a cui corrispondono rispettivamente in pin di uscita OC2A e OC2B) che condividono ovviamente la stessa configurazione del timer, ma che possono essere usati, ad esempio, per generare due segnali a frequenza uguale, ma con duty cicle diverso.

I fattori di prescaler del segnale di clock sono ben sette e segnatamente: 1, 8, 32, 64, 128, 256, 1024.

Le modalità  di funzionamento per questo timer possono essere
  • Normale: il timer conta da 0 a 255, continuamente; è una modalità  di funzionamento che offre margini di flessibilità  praticamente nulli, a meno di non ricorrere a ricaricamenti via software in fase di esecuzione o adottare particolari valori della frequenza di clock; ad esempio, con un clock di 32768 Hz e un prescaler di 1:128 si ottiene una perfetta base dei tempi da 1 secondo.

  • PWM Fast: il valore corrente del timer viene confrontato una sola volta con quello di un registro, durante la fase di conteggio da 0 verso 255.
    Quando i valori dei due registri sono fra loro uguali, al successivo clock, viene effettuata una commutazione del livello d'uscita (questo metodo è preferibile per applicazioni ad alta frequenza, in cui non sia importante la  fase del segnale PWM)

  • PWM a fase costante: il valore corrente del timer viene confrontato due volte con quello contenuto in un registro: una prima volta mentre il timer conta da 0 verso 255, una seconda volta, durante la fase di conteggio da 255 verso 0.
    All'avvenuta uguaglianza fra questi due numeri, il pin d'uscita viene commutato al successivo impulso di clock (questo metodo è richiesto per applicazioni dove è importante mantenere la fase costante, es: regolazione PWM in motori a c.c.)

La modalità  PWM fast può essere, a sua volta, implementata in tre modi:
  1. a duty cicle regolabile e periodo/frequenza non regolabile sul canale A e/o B:

  2. a duty cicle fisso al 50% e periodo/frequenza regolabile sul canale A

  3. a duty cicle fisso al 50% sul canale A e
    frequenza/periodo regolabile
    con duty cicle regolabile sul canale B
    (ma con frequenza pari alla metà  di quella sul canale A)
Per periodo/requenza regolabile si intende che nel software può essere regolata, in modo fine, il periodo (ovvero la frequenza) desiderato del segnale rettangolare; diversamente per periodo/frequenza non regolabile si intende che è possibile scegliere il periodo/frequenza, ma solo in un insieme di valori predeterminati, scegliendo quello che più si avvicina a quello desiderato

La seconda modalità  è quella consigliata da Amtel per ottenere segnali simmetrici mediante il Timer2

La terza modalità , dunque, è quella più flessibile perché consente di ottenere sul canale B del timer un segnale regolabile in duty cicle e in periodo

Quando il Timer2 lavora in modalità Fast PWM, viene attivato il buffering dei registri: all'esecuzione dell'istruzione di caricamento/aggiornamento del registro di confronto (OCR2A o OCR2B) il valore viene scritto prima in un registro temporaneo per poi essere ricopiato in quello di confronto al successivo azzeramento del registro dati TCNT2; ciò previene asimmetrie nel segnale d'uscita (glitch-free).



Logica di funzionamento della Fast PWM

La logica di funzionamento della Fast PWM è simile a quella vista per il Timer1 a 16bit.

Nella modalità  a duty cicle regolabile e frequenza non regolabile, appena il valore corrente del registro del timer2 (TCNT2) raggiungerà  un valore NA contenuto nel registro OCR2A, al sucessivo impulso di clock si avrà  la commutazione di livello, che potrà  essere da livello alto a livello basso (nel caso della modalità  non invertita) o da livello basso a livello alto (nel caso della modalità  invertita).

La modalità  non invertita è quella che corrisponde alla definizione di duty cicle ed è raffigurata di seguito, supponendo che vogliamo usare il canale A:


La lettura del nuovo valore NA, contenuto in OCR2A, viene comunque fatta dopo ogni azzeramento del registro dati TCNT2 (buffering attivato)




In questa modalità , il registro OCR1A viene sincronizzato a ogni successivo valore 0 del registro dati TCNT2, questo per evitare asimmetrie nel segnale generato.

Nella modalità  Fast PWM a frequenza non regolabile con il Timer2, si dovrà  dunque calcolare un valore (NA) che andrà  caricato nel registro OCR2A (se ovviamente usiamo il canale A) che definisce il duty cicle del segnale PWM generato sul pin OC2A.

In questo tipo di FastPWM, invece, non è possibile, modificare il numero massimo N, dal quale dipende il periodo Ts e dunque il valore di frequenza del segnale generato non potrà  essere regolato, ma scelto fra un insieme di valori (vedi tabella successiva).

Esempio applicativo


Supponiamo di avere questo semplice problema:

Usando il timer2, in modo Fast PWM, generare un segnale a 8kHz, con duty cicle del 40%. La frequenza di clock fc è  di 16 MHz (si usa una board Arduino)

A un segnale a frequenza fck corrisponde un periodo Tck:




Il periodo Ts del segnale da generare può essere calcolato dalla nota equazione generale:


ove:

Ts è il periodo del segnale PWM
 N è il numero massimo, che può contare il timer
 k è il fattore di prescaler
 Tck è il periodo del segnale di clock


e quindi, dal momento che il timer2 può contare fino a 255, il periodo del segnale Ts è calcolabile con l'equazione:


Creando un tabella con il foglio elettronico, siamo così in grado di calcolare il periodo Ts del segnale PWM (ovvero la frequenza fs) per ogni fattore di prescaler k, assegnata la frequenza di clock di 16MHz:


Come si può notare, possiamo ottenere (con un clock assegnato di 16 MHz) solo frequenze fisse aventi determinati valori, che non possiamo regolare in modo fine; scegliendo k=8 abbiamo una frequenza del segnale fs=7,81kHz che si avvicina a 8 kHz

Essendo richiesto di utilizzare il modo Fast PWM, non possiamo che accettare questo compromesso e scegliamo allora k=8

Successivamente vedremo un'altra modalità  Fast PWM che consente di regolare il valore di frequenza esattamente a 8 kHz

La regolazione del duty cicle


 
Il duty cicle si esprime in percentuale e si definisce come rapporto fra il tempo in cui il segnale è alto (Ton) e l'intero periodo del segnale (Ts) moltiplicandolo per 100.




Calcolare i due tempi è molto semplice: se per un periodo Ts occorrono N+1 cicli di clock (ossia 256), per un periodo Ton ne occorreranno di meno, diciamo NA+1 ; dunque:


 e:


sostituendo nella formula generale del dutyu cicle abbiamo:



 Da cui siamo in grado di ricavare NA per il dc% desiderato:



che per dc=40% diventa:


Il valore ricavato è stato approssimato, dal momento che i registri memorizzano numeri interi fra 0 a 255; l'effettivo duty cicle sarà  dunque:



N.B. E' sempre possibile usare anche il canale B del timer, caricando un secondo valore NB in OCR2B (ovviamente calcolato secondo la stessa metodologia di NA) ottenendo così un secondo segnale PWM che ha la stessa frequenza e modalità  del primo (dovendo condividere la stessa configurazione del timer0) ma con duty cicle diverso.


Scriviamo il programma

Vediamo ora un possibile pseudocodice per la configurazione del timer:
  1. Configura il timer2 in modo PWM Fast a risoluzione fissa
  2. Configura il modo PWM in modalità  non invertente sul canale A
  3. Carica il valore NA in OCR2A
  4. Configura il prescaler (:8), il timer è avviato
Codifichiamo i vari step in GNU avr-libc:

1. Configura timer2 in modo PWM Fast a risoluzione fissa

Si fa riferimento alla tabella 18-8 del datasheet:


Bisogna dunque settare i bit WGM21 e WGM20, che si trovano nel registro di configurazione A del Timer2 (TCCR2A) :


TCCR2A = (1 << WGM21) | (1 << WGM20);

2. Configura il modo PWM in modalità  non invertente sul canale A

Bisogna far riferimento alla Tab. 18-3 del d/sheet, che riporta come impostare i bit COM2A1 e COM2A0 del registro TCCR2A per avere la modalità  PWM non invertente.


TCCR2A |= (1 << COM2A1);

3. Carica il valore NA in OCR2A

Conviene usare un'etichetta simbolica NA associata al numero da caricare, con un commento esplicativo sul duty cicle ottenuto in corrispondenza di esso:

#define NA 102 /* dc=40% @ fck=16MHz:8 */

OCR2A = NA; // carica NA in OCR2A 


4. Configura il prescaler (:8)

La tabella 18.9 indica come settare i bit CS22, CS21 e CS20 del registro TCCR2B:


TCCR2B = (1 << CS21);


Dopo quest'ultima istruzione, il timer è così avviato.

Siamo dunque in grado di scrivere il codice definitivo, combinando assieme tutti i pezzi di codice creati passo per passo.

#include <avr/io.h>

#define NA 102  /* dc=40% @ fck=16MHz:8 */

int main (void)

{


  DDRB |= (1 << PB3);  // imposta pin PB3(OC2A) come uscita
  TCCR2A = (1 << WGM21) | (1 << WGM20) | // FastPWM a risoluzione fissa 
           (1 << COM2A1);    // PWM mod. non invertente

  OCR2A = NA;

  TCCR2B = (1 << CS21); // prescaler :8

  while(1)

  {

    /* il compito viene svolto completamente via hardware dal Timer2.. */

  }

}



Simulazione con VMLAB

File Project (per Windows non per Wine):
Si ricorda di rinominare il file ATmega168b.ini in ATmega168.ini

; Micro + software running
; ------------------------------------------------------------
.MICRO "ATmega168"      "CKSEL=0000 CKDIV8=1"
.CLOCK 16meg         ; Micro clock
.TOOLCHAIN "GCC"
.GCCPATH   "C:\WinAVR"
.GCCMAKE   AUTO
.TARGET    "pwm.hex"
.SOURCE    "main.c"

.TRACE     ; Activate micro trace

; Following lines are optional; if not included
; exactly these values are taken by default
; ------------------------------------------------------------
.POWER VDD=5 VSS=0  ; Power nodes
.STORE 50m     ; Trace (micro+signals) storage time
.PLOT V(PB3)   ; Plotta il livello del pin PB3(OC2A)

I risultati della simulazione

Ton:



e il periodo del segnale Ts:




I contenuti di questo documento, sono stati resi possibili grazie ai seguenti strumenti gratuiti:
- LaTex online equation editor
- FidoCADJ (disegno grafici)
- Google Code Prettify (sorgenti con sintassi evidenziata)
- Libreoffice Calc (calcolo valori prescaler ris. fissa)



Informativa estesa sui Cookie | Web Statistics

Clicky

| Realizzazione a cura di Francesco Parisi (2002 ÷ 2024) | Contatti